import React, { forwardRef, useContext, useMemo, useEffect } from "react"
import useMergeProps from "@/hooks/useMergeProps"
import useResponsiveState from "./hooks/useResponsiveState";
import { ConfigContext } from "../config-provider"
import { cs, isFunction, isString } from "@/utils"
import { GridContext, GridDataCollectorContext } from "./context";
import { resolveItemData } from "./util";
const defaultProps = {
    suffix: false,
    offset: 0,
    span: 1
}
/**
 *
 * @param {Object} props
 * @param {React.RefObject} ref
 * @param {boolean} [props.suffix] 是否是后缀元素
 * @param {string | string[]} [props.className] 节点类名
 * @param {number | {[key: string]: any }} [props.offset] 左侧的间隔格数
 * @param {number | {[key: string]: any }} [props.span] 跨越的格数
 * @param {React.CSSProperties} [props.style] 节点样式
 * @returns {React.ReactNode}
 */
const GridItemComponent = (gridItemProps, ref) => {
    const { getPrefixCls } = useContext(ConfigContext)
    const props = useMergeProps(gridItemProps, defaultProps)
    const {
        children,
        suffix,
        className,
        offset: propOffset,
        span: propSpan,
        style,
        __index__: computedIndex
    } = props
    const gridContext = useContext(GridContext)
    const { collectItemData, removeItemData } = useContext(GridDataCollectorContext)
    const { colGap, cols, displayIndexList, overflow } = gridContext
    const offset = useResponsiveState(propOffset, 0)
    const span = useResponsiveState(propSpan, 0)
    const prefixCls = getPrefixCls("grid-item")
    const visible = displayIndexList?.includes(computedIndex)
    const mergeClassName = {
        [`${prefixCls}`]: true
    }
    const classNames = cs(mergeClassName, className)
    const itemData = useMemo(() => {
        return resolveItemData(gridContext.cols, { suffix: !!suffix, span, offset })
    }, [gridContext.cols, suffix, span, offset])
    useEffect(() => {
        collectItemData(computedIndex, itemData)
        return () => {
            removeItemData(computedIndex)
        }
    }, [computedIndex, itemData])
    const offsetStyle = useMemo(() => {
        const { offset, span } = itemData
        if (offset > 0) {
            const oneSpan = `(100% - ${colGap * (span - 1)}px) / ${span}`
            return {
                marginLeft: `calc((${oneSpan} * ${offset}) + ${colGap * offset}px)`
            }
        }
    }, [itemData, colGap])
    const columnStart = useMemo(() => {
        const { suffix, span } = itemData
        if (suffix) {
            return `${cols - span + 1}`
        }
        return `span ${span}`
    }, [itemData, span])
    const visibleStyle = !visible || span === 0 ? { display: "none" } : {}
    const gridItemStyle = {
        gridColumn: `${columnStart} / span ${span}`,
        ...offsetStyle,
        ...visibleStyle
    }
    return (
        <div
            ref={ref}
            className={classNames}
            style={{
                ...gridItemStyle,
                ...style
            }}
        >
            {
                isFunction(children) ? children({ overflow }) :
                    React.Children.map(children, (child) => {
                        if (
                            child &&
                            gridContext.collapsed &&
                            React.isValidElement(child) &&
                            !isString(child.type)
                        ) {
                            // 排除原生标签，避免 overflow 属性透传到 dom 标签上
                            return React.cloneElement(child, {
                                overflow,
                                ...child.props
                            })
                        }
                        return child
                    })
            }
        </div>
    )
}
const GridItem = forwardRef(GridItemComponent)
GridItem.displayName = "GridItem"
export default GridItem